/*	控制请求图片最大并发数；保证同时只有三个图片在进行请求，当一张图片请求完毕时，立刻填补进去，
保证同时请求的图片数量只有三张	*/
function limitLoad(urls, handler, limit) {
	const sequence = [].concat(urls) // 对数组进行一份拷贝，不能影响到外部的数据
	let promises = []
	// 获取并发的前几张图片，返回三个promise组成的数组
	promises = sequence.splice(0, limit).map((url, index) => {
		return handler(url).then(() => {
			return index
		})
	})
	// 这里首先执行一个promise.race 返回的是一个promise和一个下标
	let p = Promise.race(promises)
	for(let i = 0; i < sequence.length; i++){ // 循环剩余的图片列表请求数组
		// 1.因为p是一个promise,而且返回promises的对应下标，所以 p.then中的res对应的是已完成的promsies列表请求的一个promise
		// 2.然后通过循环，依次将剩余的图片请求，添加到对应的已完成的promises数组中去，就可以保证始终有三个图片请求，直到最后图片请求完成
		// 3.在p.then中，重新返回一个p=Promise.race(promises);只有当异步任务已完成时，才会调用.then方法，将已完成的promises数组下标返回，将剩余的图片列表请求依次添加入已对应的已完成的promise数组
		p = p.then(res => {
			promises[res] = handler(sequence[i]).then(() => {
				return res
			})
			return Promise.race(promises)
		})
	}
}
const urls = [
	{ info: 'link1', time: 3000 },
	{ info: 'link2', time: 2000 },
	{ info: 'link3', time: 5000 },
	{ info: 'link4', time: 1000 },
	{ info: 'link5', time: 1200 },
	{ info: 'link6', time: 2000 },
	{ info: 'link7', time: 800 },
	{ info: 'link8', time: 3000 }
]
// 设置我们要执行的任务
function loadImg(url) {
	return new Promise((resolve, reject) => {
		console.log('------' + url.info + 'start!')
		setTimeout(() => {
			console.log(url.info + 'OK!!!')
			resolve()
		}, url.time)
	})
}
limitLoad(urls, loadImg, 3)